<template>
  <div
    ref="chartRef"
    class="chart-container"
    :style="{ width, height }"
  ></div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import * as echarts from 'echarts'
import { debounce } from '@/utils'

const props = defineProps({
  // 图表配置项
  options: {
    type: Object,
    required: true
  },
  // 图表类型
  type: {
    type: String,
    default: 'line'
  },
  // 图表宽度
  width: {
    type: String,
    default: '100%'
  },
  // 图表高度
  height: {
    type: String,
    default: '400px'
  },
  // 是否自动调整大小
  autoResize: {
    type: Boolean,
    default: true
  },
  // 主题
  theme: {
    type: String,
    default: ''
  },
  // 加载状态
  loading: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['chart-click', 'chart-legendselectchanged'])

// 图表实例
const chartRef = ref(null)
let chart = null

// 初始化图表
const initChart = () => {
  if (!chartRef.value) return
  
  // 创建图表实例
  chart = echarts.init(chartRef.value, props.theme)
  
  // 设置图表配置项
  setOptions()
  
  // 监听图表事件
  chart.on('click', (params) => {
    emit('chart-click', params)
  })
  
  chart.on('legendselectchanged', (params) => {
    emit('chart-legendselectchanged', params)
  })
}

// 设置图表配置项
const setOptions = () => {
  if (!chart) return
  
  // 显示加载状态
  if (props.loading) {
    chart.showLoading()
  } else {
    chart.hideLoading()
  }
  
  // 设置图表配置项
  chart.setOption(props.options)
}

// 调整图表大小
const resize = debounce(() => {
  if (chart) {
    chart.resize()
  }
}, 100)

// 监听配置项变化
watch(() => props.options, (newVal) => {
  setOptions()
}, { deep: true })

// 监听加载状态变化
watch(() => props.loading, (newVal) => {
  if (chart) {
    if (newVal) {
      chart.showLoading()
    } else {
      chart.hideLoading()
    }
  }
})

// 监听主题变化
watch(() => props.theme, (newVal) => {
  if (chart) {
    chart.dispose()
    chart = echarts.init(chartRef.value, newVal)
    setOptions()
  }
})

// 组件挂载时初始化图表
onMounted(() => {
  initChart()
  
  // 监听窗口大小变化
  if (props.autoResize) {
    window.addEventListener('resize', resize)
  }
})

// 组件卸载时销毁图表
onBeforeUnmount(() => {
  if (props.autoResize) {
    window.removeEventListener('resize', resize)
  }
  
  if (chart) {
    chart.dispose()
    chart = null
  }
})

// 暴露方法
defineExpose({
  // 获取图表实例
  getChart: () => chart,
  // 调整图表大小
  resize,
  // 设置图表配置项
  setOptions,
  // 销毁图表
  dispose: () => {
    if (chart) {
      chart.dispose()
      chart = null
    }
  }
})
</script>

<style lang="scss" scoped>
.chart-container {
  position: relative;
  
  :deep(.echarts-loading) {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(255, 255, 255, 0.9);
    z-index: 1;
  }
}
</style> 